﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.IO;
using System.Globalization;

namespace fOrganiz
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        BackgroundWorker bg = new BackgroundWorker();
       public MainWindow()
        {
            InitializeComponent();
        }


        //open dialog
        private void btnDestination_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog();
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                txtDestination.Text = dialog.SelectedPath;
        }

        //open dialog
        private void btnSource_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog();
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                txtSource.Text = dialog.SelectedPath;
        }

        // Start job
        private void btnStart_Click(object sender, RoutedEventArgs e)
        {
            // code for Can Execute in MVVM style ...
            if (string.IsNullOrWhiteSpace(txtSource.Text) || string.IsNullOrWhiteSpace(txtDestination.Text))
                return;


            if (btnStart.Content.ToString() == "Start")
            {
                lblCurrentProcessingPhotoNumber.Content = 0;
                btnStart.Content = "Stop";

                if (bg.IsBusy)
                    bg.CancelAsync();

                bg.DoWork += new DoWorkEventHandler(bg_DoWork);
                bg.ProgressChanged += new ProgressChangedEventHandler(bg_ProgressChanged);
                bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);
                bg.WorkerReportsProgress = true;
                bg.WorkerSupportsCancellation = true;
                bg.RunWorkerAsync(new WorkEventArgs { Source = txtSource.Text, Destination = txtDestination.Text, Pattern = txtPattern.Text });
            }
            else
            {
                if (bg.IsBusy)
                    bg.CancelAsync();

                btnStart.Content = "Start";
            }
            

        }

        void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MessageBox.Show("Done !", "Done", MessageBoxButton.OK, MessageBoxImage.Information);
            btnStart.Content = "Start";
        }

        void bg_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
           int i = (int)lblCurrentProcessingPhotoNumber.Content;
           lblCurrentProcessingPhotoNumber.Content = ++i;
        }

        void bg_DoWork(object sender, DoWorkEventArgs e)
        {
            
            WorkEventArgs args = e.Argument as WorkEventArgs;
            if (Directory.Exists(args.Source))
            {
                BrowseDirectory(args);
            }
        }

        void BrowseDirectory(WorkEventArgs args)
        {
            if(bg.CancellationPending)
                return;


            if (Directory.Exists(args.Source))
            {
                foreach (var item in Directory.EnumerateDirectories(args.Source))
                {
                    BrowseDirectory(new WorkEventArgs{ Source = item,Destination = args.Destination,Pattern = args.Pattern});
                }

                foreach (var item in Directory.EnumerateFiles(args.Source))
                {
                    if (item.ToUpperInvariant().EndsWith(".JPG"))
                        OrganizePicture(new WorkEventArgs { Source = item, Destination = args.Destination, Pattern = args.Pattern });
                }
            }
        }

        private void OrganizePicture(WorkEventArgs args)
        {
            if (bg.CancellationPending)
                return;


            string destinationDir =args.Destination + System.IO.Path.DirectorySeparatorChar + GetDateTaken(args.Source).ToString(args.Pattern);

            if (!Directory.Exists(destinationDir))
                Directory.CreateDirectory(destinationDir);

            string DestinationFileName = destinationDir + System.IO.Path.DirectorySeparatorChar + System.IO.Path.GetFileName(args.Source);
            File.Copy(args.Source, DestinationFileName,true);

            bg.ReportProgress(1);

        }


        private DateTime GetDateTaken(string path)
        {
        BitmapSource bs = null;
        BitmapDecoder decoder;
        if (File.Exists(path))
        {
            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                decoder = BitmapDecoder.Create(fs, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
    
               if (decoder != null)
               {
                   bs = decoder.Frames[0];
               }
    
               fs.Close();
           }
            BitmapMetadata meta = bs.Metadata as BitmapMetadata;
           DateTime DateTaken = DateTime.Parse(meta.DateTaken); // System must be in same culture that camera settings
            return DateTaken;
        }
          throw new ApplicationException("Can't read picture Date");
    }

        class WorkEventArgs
        {
            public string Source{get;set;}
            public string Destination { get; set; }
            public string Pattern { get; set; }
        }
    }
}
